package com.z.redis.command.impl.list;

import com.z.redis.RedisCore;
import com.z.redis.command.WriteCommand;
import com.z.redis.datatype.BytesWrapper;
import com.z.redis.datatype.RedisData;
import com.z.redis.datatype.RedisList;
import com.z.redis.resp.BulkString;
import com.z.redis.resp.Resp;
import com.z.redis.resp.RespInt;
import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.function.BiConsumer;

import java.util.List;

public abstract class Push implements WriteCommand {
    BiConsumer<RedisList, List<BytesWrapper>> biConsumer; // 用于操作RedisList的函数式接口
    private BytesWrapper key; // 存储命令中的键
    private List<BytesWrapper> value; // 存储命令中的值

    public Push(BiConsumer <RedisList,List<BytesWrapper>> biConsumer){
        this.biConsumer = biConsumer;
    }

    /**
     * push mylist a b c
     * @param array 命令内容
     */
    @Override
    public void setContent(Resp[] array){
        key = ((BulkString) array[1]).getContent();
        value = new ArrayList<>();
        for(int i=2;i<array.length;i++){
            value.add(((BulkString) array[i]).getContent());
        }
    }

    @Override
    public void handle(ChannelHandlerContext ctx, RedisCore redisCore){
        RedisData redisData = redisCore.get(key);
        if(redisData == null){ // 如果键不存在 新建一个列表
            RedisList redisList = new RedisList();
            biConsumer.accept(redisList,value); // 推入元素到新的列表
            redisCore.put(key,redisList); // 存入数据库
            ctx.writeAndFlush(new RespInt(redisList.size()));
        }else if(redisData != null && !(redisData instanceof RedisList)){
            ctx.writeAndFlush(new Error("wrong type")); // 键存在但不是列表类型
        }else{
            biConsumer.accept((RedisList) redisData,value); // 推入元素到已存在的列表
            redisCore.put(key,redisData); // 更新数据库
            ctx.writeAndFlush(new RespInt(((RedisList) redisData).size()));
        }
    }

    @Override
    public void handle(RedisCore redisCore){
        RedisData redisData = redisCore.get(key);
        if(redisData == null){ // 如果键不存在 新建一个列表
            RedisList redisList = new RedisList();
            biConsumer.accept(redisList,value); // 推入元素到新的列表
            redisCore.put(key,redisList); // 存入数据库
        }else if(redisData!=null && !(redisData instanceof RedisList)){

        }else{
            biConsumer.accept((RedisList) redisData,value); // 推入元素到已存在的列表
            redisCore.put(key,redisData); // 更新数据库
        }
    }
}
